package com.sercomm.ott.mediaplayer;

import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.content.Context;
import android.content.Intent;
import android.media.MediaMetadataRetriever;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Build;
import android.util.Log;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.File;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by 10978 on 6/15/17.
 */

public class SystemStatus {
    private final static String TAG = "cpuinfo";

    public static final String SYSTEM_WRITE_SERVICE_API19 = "system_write";
    public static final String SYSTEM_WRITE_CLASS_API19 = "android.app.SystemWriteManager";
    public static final String READ_SYSFS_API19 = "readSysfs";
    public static final String WRITE_SYSFS_API19 = "writeSysfs";
    // for amlogic android 7.1.1 S905X - com.droidlogic.app.SystemControlManager
    public static final String SYSTEM_WRITE_SERVICE_API25 = "system_control";
    public static final String SYSTEM_WRITE_CLASS_API25 = "com.droidlogic.app.SystemControlManager";
    public static final String READ_SYSFS_API25 = "readSysFs";
    public static final String WRITE_SYSFS_API25 = "writeSysFs";

    public static Object system_manager = null;
    public static Method sm_readSysfs = null;
    public static Method sm_writeSysfs = null;

    public static String readSysfs(final String file){
        String res = "";
        try {
            res = (String) sm_readSysfs.invoke(system_manager,file);
            //log("readSysfs - "+file+" : "+res);
        }catch (Exception e){
            e.printStackTrace();
            Log.d(TAG,"readSysfs - " + file + " : failure");
        }
        return res;
    }

    public static void writeSysfs(final String file, final String value){
        try{
            sm_writeSysfs.invoke(system_manager,file,value);
        }catch (Exception e){
            e.printStackTrace();
            Log.d(TAG,"writeSysfs - "+file+" value - "+value +" : failure");
        }
    }

    public static void initSystemManager(final Context context){
        //if (system_manager!=null) return;
        switch (Build.VERSION.SDK_INT) {
            case 19:
                try {
                    system_manager = context.getSystemService(SYSTEM_WRITE_SERVICE_API19);
                    sm_readSysfs = system_manager.getClass().getDeclaredMethod(READ_SYSFS_API19,String.class);
                    sm_writeSysfs = system_manager.getClass().getDeclaredMethod(WRITE_SYSFS_API19, String.class, String.class);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.d(TAG,"get system service : " + SYSTEM_WRITE_SERVICE_API19 + " failure");
                }
                break;
            case 25:
                try {
                    Class<?> cls = Class.forName(SYSTEM_WRITE_CLASS_API25);
                    Constructor<?> constructor = cls.getConstructor(Context.class);
                    system_manager = constructor.newInstance(context);
                    sm_readSysfs = system_manager.getClass().getDeclaredMethod(READ_SYSFS_API25,String.class);
                    sm_writeSysfs = system_manager.getClass().getDeclaredMethod(WRITE_SYSFS_API25, String.class, String.class);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.d(TAG,"create object : " + SYSTEM_WRITE_CLASS_API25 + " failure");
                }
                break;
            default:
                Log.d(TAG,"Unsupport Android API : "+Build.VERSION.SDK_INT);
        }
    }

    /*
     * video status
     *  1.frame width ,2.frame height,3.frame rate fps, 4.bit rate kbps, 5.status, 6.frame dur, 7.frame data KB
     *  8.frame count ,9.drop count ,10.fra err count, 11.hw err count,12.total data KB
     */
    public static List<String> getVideoStatus(){
        String path = "/sys/class/vdec/vdec_status";
        String res = "no";
        List<String> list =null;

        try {
            res = readSysfs(path);
            if(res.contains("No vdec")){
                return list;
            }
            list =Arrays.asList(res.split(":"));
            list=list.subList(3,list.size());
            for(int i=0 ;i<list.size();i++){
                String tmp = list.get(i).trim();
                list.set(i,tmp.substring(0,tmp.indexOf(" ")));
                if(i==8) {
                    list.set(i, tmp.substring(0, tmp.indexOf("fra")));
                }
                //Log.d(TAG,"------davis list "+i +" "+list.get(i));
            }
            //Log.d(TAG,"------davis vdec_status---"+res);
        }catch (Exception e){
            e.printStackTrace();
        }
        return list;
    }
    public static String getStrVideoStatus(){
        String path = "/sys/class/vdec/vdec_status";
        String res = "no";
        try{
            res = readSysfs(path);
        }catch (Exception e){
            e.printStackTrace();
        }
        return res;
    }
    //no permission
    public static String getVdecStatus(){
        String path = "/sys/class/vdec/vdec_status";
        String line = "";
        String arrs[] =null;
        try {
            BufferedReader br = new BufferedReader(new FileReader(path));
            while ((line=br.readLine())!=null){
                arrs = line.split(":");
                Log.d(TAG,"-----davis---line "+arrs[1]);
            }
        }catch (Exception e){
            e.printStackTrace();
        }

        return "";
    }
    /*
     * memory loading
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    public static double getMemoryLoading(Context mContext) {
        ActivityManager am = (ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE);
        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
        am.getMemoryInfo(mi);
        //LogUtil.d(TAG,"totalmem "+ mi.totalMem+" availmem "+mi.availMem);
        return 100.0 * (mi.totalMem - mi.availMem) / mi.totalMem;
    }

    /*
     * cpu loading
     */
    public static String getCpuLoading() {
        String tp = "/proc/stat";
        String cLoad = "";
        String[] result;
        long allLoad = 0;
        long availLoad = 0;
        String twoInfo = "1 1";

        try {
            FileReader fr = new FileReader(tp);
            BufferedReader bf = new BufferedReader(fr);
            cLoad = bf.readLine();
            cLoad = cLoad.substring(cLoad.indexOf(" ")).trim();
            //LogUtil.d(TAG, "------" + cLoad);
            result = cLoad.split(" ");

            for (int i = 0; i < result.length; i++) {
                // LogUtil.d(TAG, "---result" + i + " = " + result[i]);
                // LogUtil.d(TAG, "----parselong" + i + " = " + Long.parseLong(result[i]));
                allLoad += Long.parseLong(result[i]);
            }
            availLoad = Long.parseLong(result[3]);
            twoInfo = String.valueOf(allLoad) + " " + String.valueOf(availLoad);
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        // LogUtil.d(TAG, "--------" + twoInfo);
        return twoInfo;
    }


    /*
     * cpu load percent
     */
    public static double getCpuLoadPercent(String start,String end) {
        double percent = 0;
        try{
            long all = Long.parseLong(end.substring(0,end.indexOf(' ')).trim())
                    - Long.parseLong(start.substring(0,start.indexOf(' ')).trim());
            long avail = Long.parseLong(end.substring(end.indexOf(' ')).trim())
                    - Long.parseLong(start.substring(start.indexOf(' ')).trim());
            percent = 100.0*(all-avail)/all *(SystemStatus.getCpuCores()-SystemStatus.getCpuIdle())/SystemStatus.getCpuCores();
        }catch (Exception e){
            e.printStackTrace();
        }

        return percent;
    }
    /*
    public static String getCpuLoading(Context mContext){
        String tp="/proc/loadavg";
        String[] result;
        String cLoad="";
        try{
            FileReader fr = new FileReader(tp);
            BufferedReader bf = new BufferedReader(fr);
            cLoad = bf.readLine();
        }catch (IOException e){
            e.printStackTrace();
        }
        result=cLoad.split(" ");
        return result[0];
    }
    */

    /*
     * cpu temperature   S005X no permission
     */
    public static int getCpuTemperature(Context mContext) {
        String temp = "/sys/class/thermal/thermal_zone0/temp";
        String cTemp = "";
        try {
            FileReader fr = new FileReader(temp);
            BufferedReader bf = new BufferedReader(fr);
            cTemp = bf.readLine();
            fr.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //LogUtil.d(TAG,"---temperature "+Integer.parseInt(cTemp)/1000);
        return Integer.parseInt(cTemp) / 1000;
    }
    public static int getCpuTemperatureSM(){
        int temp = 0;     // 65 C
        final String file = "/sys/class/thermal/thermal_zone0/temp";
        try {
            String res = readSysfs(file);
            temp = Integer.parseInt(res.trim());
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return temp <1000 ? temp : temp/1000;       // trans to C
    }

    /*
     * product name
     */
    public static String getModuleName(Context mContext) {

        return Build.PRODUCT;
    }

    /*
     * device serial number
     */
    public static String getSerialNum(Context mContext) {

        return Build.SERIAL;
    }

    public static String getSerialNumberSM(){
        String sn = "Unknown";      // 80283408203
        final String file = "/proc/cpuinfo";
        final String type = "serial";
        try{
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = null;
            while((line = br.readLine())!=null) {
                Log.d(TAG,"read " + file + " : " + line);
                if (line.toLowerCase().startsWith(type)) {
                    sn = line.substring(line.indexOf(':') + 1).trim();
                    break;
                }
            }
            br.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        //return Build.SERIAL;      // Not Correct!
        return sn;
    }
    /*
     * ethernet link
     */
    public static boolean isEthernetOn(Context mContext) {
        ConnectivityManager connectivity = (ConnectivityManager) mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connectivity != null) {
            NetworkInfo info = connectivity.getActiveNetworkInfo();
            if (info != null && info.isConnected()) {
                return true;
            }
        }
        return false;
    }

    /*
     * linkspeed no permisson
     */
    public static int getEthernetSpeed(){
        int speed = 0;        // 100  // Mbps
        final String file = "/sys/class/net/eth0/speed";
        try{
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();
            speed = Integer.parseInt(line.trim());
            br.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        return speed;
    }
    public static int getEthernetSpeedSM(){
        int speed = 0;     // 65 C
        final String file = "/sys/class/net/eth0/speed";
        try {
            String res = readSysfs(file);
            speed = Integer.parseInt(res.trim());
        }
        catch (Exception e){
            e.printStackTrace();
        }
        return speed;       // trans to C
    }

    /*
     * ethernet duplex no permisson
     */
    public static String getEthernetDuplex() {
        String duplex = "Unknown";        // Full
        final String file = "/sys/class/net/eth0/duplex";
        try {
            BufferedReader br = new BufferedReader(new FileReader(file));
            String line = br.readLine();
            duplex = line.trim();
            br.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return duplex;
    }
    public static String getEthernetDuplexSM(){
        final String file = "/sys/class/net/eth0/duplex";
        String res = readSysfs(file);
        Log.d(TAG,"readSysfs - "+file+" : "+res);
        return res;
    }
    /*
     * devide mac address no permission
     */
    public static String getMacAddr(Context mContext) {
        String addrpath = "/sys/class/net/eth0/address";
        String macString = null;
        try {
            FileReader fr = new FileReader(addrpath);
            BufferedReader bf = new BufferedReader(fr);
            macString = bf.readLine();
            fr.close();
            return macString.trim();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return "##";
    }
    public static String getEthernetMacSM(){
        final String file = "/sys/class/net/eth0/address";
        String res = readSysfs(file);
        Log.d(TAG,"readSysfs - "+file+" : "+res);
        return res;
    }

    /*
        public static int getVideoFrames(Context mContext,String pathString){

            MediaMetadataRetriever mmdr = new MediaMetadataRetriever();
            mmdr.setDataSource(pathString);
            String result = mmdr.extractMetadata(MediaMetadataRetriever.METADATA_KEY_CAPTURE_FRAMERATE);
            mmdr.release();
            LogUtil.d(TAG,"------getvideoframes "+result);
            return Integer.parseInt(result);
        }
    */

    /*
     * cpu core number
     */
    public static int getCpuCores() {
        int cores = 0;       // 4
        final String file = "/sys/devices/system/cpu/";
        final String cpu = "cpu";
        try {
            File dir = new File(file);
            String[] fs = dir.list();
            for (int i = 0; i < fs.length; ++i) {
                if (fs[i].startsWith(cpu)) {
                    String tmp = fs[i].substring(cpu.length());
                    try {
                        if (tmp.equals("" + Integer.parseInt(tmp)))
                            ++cores;
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        //LogUtil.d(TAG,"------corenum "+cores);
        return cores;
    }

    /*
     * cpu core idle number
     */
    public static int getCpuIdle(){
        int idle = 0;
        String idlepath = "/sys/devices/system/cpu/offline";
        String sIdle = "";
        try{
            FileReader fr = new FileReader(idlepath);
            BufferedReader bf = new BufferedReader(fr);
            sIdle = bf.readLine().trim();
            String s[] = sIdle.split("-");
            if(s.length == 1){
                idle = 1;
            }else {
                idle = Integer.parseInt(s[1])-Integer.parseInt(s[0])+1;
            }
            fr.close();
        }catch (Exception e){
            e.printStackTrace();
        }
        //LogUtil.d(TAG,"-----idle  "+idle);
        return idle;

    }

    public static String getCpuLoad(){
        final String cmd = "dumpsys cpuinfo | tail -n 1";
        final String[] res =runSystemCommand(cmd);
        String cpuLoad = "0";
        try {
            Log.d(TAG,"----davis---cpuload "+res[0]);
            cpuLoad=res[0].substring(0,res[0].indexOf("%"));
        }catch (Exception e){
            e.printStackTrace();
        }
        return cpuLoad;

    }

    public static String getEthernetIp(){
        final String cmd = "busybox ifconfig eth0";
        final String[] res = SystemStatus.runSystemCommand(cmd);
        final String type_ipv4 = "inet addr";
        final String type_mask = "Mask";
        String ipv4 = "Unknown";        // 192.168.1.5
        String mask = "Unknown";        // 255.255.255.0
        for(int i=0; i<res.length; ++i) {
            if (res[i].toLowerCase().contains(type_ipv4)) {
                Log.d(TAG,"-----davis----Run res: " + res[i]);
                ipv4 = res[i].substring(res[i].indexOf(type_ipv4));
                ipv4 = ipv4.substring(ipv4.indexOf(':')+1);
                ipv4 = ipv4.substring(0,ipv4.indexOf(' '));
                ipv4 = ipv4.trim();
            }
            if (res[i].contains(type_mask)) {
                Log.d(TAG,"----davis-----Run res: " + res[i]);
                mask = res[i].substring(res[i].indexOf(type_mask));
                mask = mask.substring(mask.indexOf(':')+1);
                mask = mask.trim();
            }
        }
        return ipv4 + " / " +mask;
    }

    public static String getWlanIp(){
        final String cmd = "busybox ifconfig wlan0";
        final String[] res = SystemStatus.runSystemCommand(cmd);
        final String type_ipv4 = "inet addr";
        final String type_mask = "Mask";
        String ipv4 = "Unknown";        // 192.168.1.5
        String mask = "Unknown";        // 255.255.255.0
        for(int i=0; i<res.length; ++i) {
            if (res[i].toLowerCase().contains(type_ipv4)) {
                Log.d(TAG,"-----davis----Run res: " + res[i]);
                ipv4 = res[i].substring(res[i].indexOf(type_ipv4));
                ipv4 = ipv4.substring(ipv4.indexOf(':')+1);
                ipv4 = ipv4.substring(0,ipv4.indexOf(' '));
                ipv4 = ipv4.trim();
            }
            if (res[i].contains(type_mask)) {
                Log.d(TAG,"-----davis----Run res: " + res[i]);
                mask = res[i].substring(res[i].indexOf(type_mask));
                mask = mask.substring(mask.indexOf(':')+1);
                mask = mask.trim();
            }
        }
        return ipv4 + " / " +mask;
    }

    public static String[] runSystemCommand(final String cmd){
        ArrayList<String> list = new ArrayList<>();
        try{
            Process proc = Runtime.getRuntime().exec(cmd);
            BufferedReader br = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            while((line = br.readLine())!=null){
                list.add(line);
            }
            br.close();
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        Log.d(TAG,"-----davis runSystemCommand list size "+list.size());
        String[] strs = new String[list.size()];
        for(int i=0; i<list.size(); ++i){
            strs[i] = list.get(i);
        }
        return strs;
    }
}







